package com.mlamp.二叉树;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class 序列化二叉树 {

    public static void main(String[] args) {
        TNode tNode = initTreeNode();
        StringBuffer sb = new StringBuffer();
        serializeTNode(tNode, sb);
        System.out.println(sb.toString());
        String input = sb.toString();
        String[] split = input.split(",");
        List<String> strings = Arrays.asList(split);
        TNode tNode1 = deserializeTNode(new ArrayList<>(strings));
        System.out.println(tNode.value);

        sb = new StringBuffer();
        serializeTNodeA(tNode, sb);
        System.out.println(sb.toString());
        String s = sb.toString();
        String[] serializeResult = s.split(",");
        List<String> strings1 = Arrays.asList(serializeResult);
        TNode tNode2 = deSerializeD(new ArrayList<>(strings1));
        System.out.println(tNode2.value);


    }

    /**
     * 先序遍历二叉树
     *
     * @param root
     * @param sb
     */
    public static void serializeTNode(TNode root, StringBuffer sb) {
        if (root == null) {
            sb.append("None").append(",");
            return;
        }
        sb.append(root.value).append(",");
        serializeTNode(root.left, sb);
        serializeTNode(root.right, sb);
    }


    public static void serializeTNodeA(TNode root, StringBuffer sb) {
        if (root == null) {
            sb.append("None").append(",");
            return;
        }
        sb.append(root.value).append(",");
        serializeTNodeA(root.left, sb);
        serializeTNodeA(root.right, sb);
    }

    public static TNode deSerializeD(ArrayList<String> sb) {
        if (sb == null || (sb.size() > 0 && sb.get(0).equals("None")) || (sb.isEmpty())) {
            if (!sb.isEmpty()) {
                sb.remove(0);
            }
            return null;
        }
        String value = sb.get(0);
        Integer integer = Integer.valueOf(value);
        sb.remove(0);
        TNode root = new TNode(integer);
        root.left = deSerializeD(sb);
        root.right = deSerializeD(sb);
        return root;
    }


    public static void serialize(TNode root, StringBuffer sb) {
        if (root == null) {
            sb.append("None").append(",");
            return;
        }
        sb.append(root.value).append(",");
        serialize(root.left, sb);
        serialize(root.right, sb);
    }


    /**
     * 序列化二叉树
     *
     * @param root
     * @param sb
     */

    public static void serializeTree(TNode root, StringBuffer sb) {
        if (root == null) {
            sb.append("none").append(",");
            return;
        }
        sb.append(root.value).append(",");
        serializeTree(root.left, sb);
        serializeTree(root.right, sb);
    }

    public static TNode deserializeTree(List<String> trace) {
        if (trace.isEmpty() || trace.get(0).equals("None")) {
            if (trace.size() > 0) trace.remove(0);
            return null;
        }
        Integer integer = Integer.valueOf(trace.get(0));
        TNode root = new TNode(integer);
        trace.remove(0);
        root.left = deserializeTree(trace);
        root.right = deserializeTree(trace);
        return root;
    }


    public static void serializeA(TNode root, StringBuffer sb) {
        if (root == null) {
            sb.append("None").append(",");
            return;
        }
        sb.append(root.value).append(",");
        serializeA(root.left, sb);
        serializeA(root.right, sb);
    }


    public static TNode deSerializeA(List<String> result) {


        if (result.isEmpty() || result.get(0).equals("None")) {
            if (result.size() > 0) result.remove(0);
            return null;
        }
        String s = result.get(0);
        Integer integer = Integer.valueOf(s);
        TNode root = new TNode(integer);
        result.remove(0);
        root.left = deSerializeA(result);
        root.right = deSerializeA(result);
        return root;
    }


    public static TNode deSerialize(List<String> result) {
        if (result.isEmpty()
                || result.get(0).equals("None")) {
            if (!result.isEmpty()) {
                result.remove(0);
            }
            return null;
        }

        Integer integer = Integer.parseInt(result.get(0));
        TNode root = new TNode(integer);
        result.remove(0);
        root.left = deSerialize(result);
        root.right = deSerialize(result);
        return root;
    }


    public static void serializeTNode(TNode root, StringBuilder sb) {
        if (root == null) {
            sb.append("None").append(",");
            return;
        }
        sb.append(root.value).append(",");
        serializeTNode(root.left, sb);
        serializeTNode(root.right, sb);
    }


    public static void serializeNode2(TNode root, StringBuffer sb) {
        if (root == null) {
            sb.append("None").append(",");
            return;
        }
        sb.append(root.value).append(",");
        serializeTNode(root.left, sb);
        serializeTNode(root.right, sb);
    }


    public static TNode deSerializeTNode23323(ArrayList<String> res) {
        if (res == null || res.isEmpty() || res.get(0).equals("None")) {
            if (res.size() > 0) res.remove(0);
            return null;
        }
        Integer integer = Integer.getInteger(res.get(0));
        TNode root = new TNode(integer);
        res.remove(0);
        root.left = deSerializeTNode23323(res);
        root.right = deSerializeTNode23323(res);
        return root;
    }


    public static TNode deSerializeTNode(ArrayList<String> res) {
        if (res == null || res.isEmpty() || res.get(0).equals("None")) {
            if (res.size() > 0) res.remove(0);
            return null;
        }
        Integer integer = Integer.getInteger(res.get(0));
        TNode root = new TNode(integer);
        res.remove(0);
        root.left = deSerializeTNode(res);
        root.right = deSerializeTNode(res);
        return root;
    }


    public static TNode deSerializeNode2(ArrayList<String> nodes) {
        if (nodes == null || nodes.isEmpty() || nodes.get(0).equals("None")) {
            if (nodes.size() > 0) {
                nodes.remove(0);
            }
            return null;
        }
        Integer integer = Integer.valueOf(nodes.get(0));
        TNode root = new TNode(integer);
        nodes.remove(0);
        root.left = deSerializeNode2(nodes);
        root.right = deSerializeNode2(nodes);
        return root;
    }


    public static TNode deserializeTNode(ArrayList<String> nodes) {
        if (nodes == null || nodes.isEmpty() || nodes.get(0).equals("None")) {
            if (nodes.size() > 0)
                nodes.remove(0);
            return null;
        }
        Integer integer = Integer.valueOf(nodes.get(0));
        TNode root = new TNode(integer);
        nodes.remove(0);
        root.left = deserializeTNode(nodes);
        root.right = deserializeTNode(nodes);
        return root;
    }


    public static TNode initTreeNode() {
        TNode root = new TNode(1);
        root.left = new TNode(2);
        root.right = new TNode(3);
        root.left.left = new TNode(4);
        root.left.right = new TNode(5);
        root.right.right = new TNode(6);
        return root;

    }


    private static class TNode {
        TNode left;
        TNode right;
        int value;

        public TNode(int value) {
            this.value = value;
            this.left = this.right = null;
        }
    }
}
